import { ModelConfigInfo } from '@/types/model-config';

const API_BASE = import.meta.env.VITE_API_URL || import.meta.env.REACT_APP_API_URL || 'http://localhost:8002';

export interface ApiKey {
  id: string;
  name: string;
  key: string;
  provider: string;
  createdAt: Date;
  updatedAt?: Date;
  lastUsedAt?: Date;
  status: 'active' | 'inactive' | 'expired';
  usageCount?: number;
  usageLimit?: number;
  expiresAt?: Date;
}

export interface ApiKeyCreateRequest {
  name: string;
  key: string;
  provider: string;
  expiresAt?: Date;
}

export interface ApiKeyUpdateRequest {
  name?: string;
  status?: 'active' | 'inactive';
  expiresAt?: Date;
}

export interface ApiKeyValidationResult {
  valid: boolean;
  provider?: string;
  error?: string;
  remaining?: number;
  limit?: number;
}

export interface ApiKeyUsageStats {
  totalUsage: number;
  dailyUsage: number;
  monthlyUsage: number;
  remainingQuota: number;
  lastUsedAt?: Date;
}

class ApiKeyService {
  private cryptoKey: CryptoKey | null = null;
  private iv: Uint8Array | null = null;
  private debounceTimers: Map<string, NodeJS.Timeout> = new Map();
  private rateLimitCache: Map<string, { count: number; resetTime: number }> = new Map();
  private readonly RATE_LIMIT_MAX = 10; // requests per minute
  private readonly DEBOUNCE_DELAY = 300; // milliseconds

  constructor() {
    this.initializeCrypto();
  }

  /**
   * 初始化Web Crypto API密钥
   */
  private async initializeCrypto(): Promise<void> {
    try {
      // 生成AES-GCM密钥用于加密
      this.cryptoKey = await crypto.subtle.generateKey(
        {
          name: 'AES-GCM',
          length: 256
        },
        false, // 不可导出
        ['encrypt', 'decrypt']
      );
      
      // 生成随机初始化向量
      this.iv = crypto.getRandomValues(new Uint8Array(12));
    } catch (error) {
      console.error('Failed to initialize crypto:', error);
      // 降级到环境变量加密（生产环境不应出现此情况）
      this.cryptoKey = null;
    }
  }

  /**
   * 使用Web Crypto API加密API密钥
   */
  private async encryptKey(key: string): Promise<string> {
    if (!this.cryptoKey || !this.iv) {
      // 降级到Base64（仅用于开发环境）
      console.warn('Crypto not available, using Base64 encoding');
      return btoa(key);
    }

    try {
      const encoder = new TextEncoder();
      const data = encoder.encode(key);
      
      const encrypted = await crypto.subtle.encrypt(
        {
          name: 'AES-GCM',
          iv: this.iv
        },
        this.cryptoKey,
        data
      );
      
      // 合并IV和加密数据
      const combined = new Uint8Array(this.iv.length + encrypted.byteLength);
      combined.set(this.iv);
      combined.set(new Uint8Array(encrypted), this.iv.length);
      
      // 转换为Base64用于传输
      return btoa(String.fromCharCode(...combined));
    } catch (error) {
      console.error('Encryption failed:', error);
      throw new Error('Failed to encrypt API key');
    }
  }

  /**
   * 使用Web Crypto API解密API密钥
   */
  private async decryptKey(encryptedKey: string): Promise<string> {
    if (!this.cryptoKey) {
      // 降级到Base64解码
      try {
        return atob(encryptedKey);
      } catch {
        return encryptedKey;
      }
    }

    try {
      // 从Base64解码
      const combined = new Uint8Array(
        atob(encryptedKey).split('').map(char => char.charCodeAt(0))
      );
      
      // 分离IV和加密数据
      const iv = combined.slice(0, 12);
      const encrypted = combined.slice(12);
      
      const decrypted = await crypto.subtle.decrypt(
        {
          name: 'AES-GCM',
          iv: iv
        },
        this.cryptoKey,
        encrypted
      );
      
      const decoder = new TextDecoder();
      return decoder.decode(decrypted);
    } catch (error) {
      console.error('Decryption failed:', error);
      throw new Error('Failed to decrypt API key');
    }
  }

  /**
   * 速率限制检查
   */
  private checkRateLimit(operation: string): boolean {
    const now = Date.now();
    const key = `${operation}_${Math.floor(now / 60000)}`; // 按分钟计算
    
    const current = this.rateLimitCache.get(key) || { count: 0, resetTime: now + 60000 };
    
    if (now > current.resetTime) {
      // 重置计数器
      current.count = 0;
      current.resetTime = now + 60000;
    }
    
    if (current.count >= this.RATE_LIMIT_MAX) {
      return false;
    }
    
    current.count++;
    this.rateLimitCache.set(key, current);
    return true;
  }

  /**
   * 防抖包装器
   */
  private debounce<T extends any[]>(
    func: (...args: T) => Promise<any>,
    key: string
  ): (...args: T) => Promise<any> {
    return (...args: T) => {
      return new Promise((resolve, reject) => {
        // 清除之前的定时器
        const existingTimer = this.debounceTimers.get(key);
        if (existingTimer) {
          clearTimeout(existingTimer);
        }
        
        // 设置新的定时器
        const timer = setTimeout(async () => {
          try {
            const result = await func(...args);
            resolve(result);
          } catch (error) {
            reject(error);
          } finally {
            this.debounceTimers.delete(key);
          }
        }, this.DEBOUNCE_DELAY);
        
        this.debounceTimers.set(key, timer);
      });
    };
  }

  /**
   * 生成CSRF令牌
   */
  private generateCSRFToken(): string {
    const array = new Uint8Array(32);
    crypto.getRandomValues(array);
    return btoa(String.fromCharCode(...array));
  }

  /**
   * 获取或生成CSRF令牌
   */
  private getCSRFToken(): string {
    let token = sessionStorage.getItem('csrf_token');
    if (!token) {
      token = this.generateCSRFToken();
      sessionStorage.setItem('csrf_token', token);
    }
    return token;
  }

  /**
   * 掩码API密钥用于显示
   */
  maskApiKey(key: string): string {
    if (!key) return '***';
    // 临时禁用掩码，直接返回完整密钥
    return key;
    // if (key.length < 8) return '***';
    // const prefix = key.substring(0, 3);
    // const suffix = key.substring(key.length - 4);
    // return `${prefix}...${suffix}`;
  }

  /**
   * 获取所有API密钥
   */
  async getAllKeys(): Promise<ApiKey[]> {
    try {
      const response = await fetch(`${API_BASE}/keys`, {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.getToken()}`
        }
      });

      // 如果端点不存在(404)，静默返回空数组
      if (response.status === 404) {
        console.log('[API Key Service] /keys endpoint not implemented yet, using empty array');
        return [];
      }

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const result = await response.json();
      return result.data || [];
    } catch (error) {
      // 网络错误或其他错误，返回空数组
      console.log('[API Key Service] Failed to fetch API keys, using empty array:', error instanceof Error ? error.message : 'Unknown error');
      return [];
    }
  }

  /**
   * 创建新的API密钥（带防抖和速率限制）
   */
  async createKey(request: ApiKeyCreateRequest): Promise<ApiKey> {
    if (!this.checkRateLimit('createKey')) {
      throw new Error('Rate limit exceeded. Please try again later.');
    }

    const debouncedCreate = this.debounce(async (req: ApiKeyCreateRequest) => {
      try {
        const encryptedRequest = {
          ...req,
          key: await this.encryptKey(req.key)
        };

        const response = await fetch(`${API_BASE}/keys`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.getToken()}`,
            'X-CSRF-Token': this.getCSRFToken()
          },
          body: JSON.stringify(encryptedRequest)
        });

        if (!response.ok) {
          const errorText = await response.text();
          throw new Error(`Request failed with status ${response.status}`);
        }

        return await response.json();
      } catch (error) {
        console.error('Failed to create API key');
        throw new Error('Failed to create API key. Please check your input and try again.');
      }
    }, `createKey_${JSON.stringify(request)}`);

    return debouncedCreate(request);
  }

  /**
   * 更新API密钥
   */
  async updateKey(id: string, request: ApiKeyUpdateRequest): Promise<ApiKey> {
    try {
      const response = await fetch(`${API_BASE}/keys/${id}`, {
        method: 'PUT',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.getToken()}`
        },
        body: JSON.stringify(request)
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Failed to update API key:', error);
      throw error;
    }
  }

  /**
   * 删除API密钥
   */
  async deleteKey(id: string): Promise<void> {
    try {
      const response = await fetch(`${API_BASE}/keys/${id}`, {
        method: 'DELETE',
        headers: {
          'Authorization': `Bearer ${this.getToken()}`
        }
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
    } catch (error) {
      console.error('Failed to delete API key:', error);
      throw error;
    }
  }

  /**
   * 验证API密钥（带防抖和速率限制）
   */
  async validateKey(provider: string, key: string): Promise<ApiKeyValidationResult> {
    if (!this.checkRateLimit('validateKey')) {
      throw new Error('Rate limit exceeded. Please try again later.');
    }

    const debouncedValidate = this.debounce(async (prov: string, k: string) => {
      try {
        const response = await fetch(`${API_BASE}/keys/validate`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.getToken()}`,
            'X-CSRF-Token': this.getCSRFToken()
          },
          body: JSON.stringify({
            provider: prov,
            key: await this.encryptKey(k)
          })
        });

        if (!response.ok) {
          throw new Error(`Request failed with status ${response.status}`);
        }

        return await response.json();
      } catch (error) {
        console.error('API key validation failed');
        return {
          valid: false,
          provider: prov,
          error: 'Validation failed. Please check your API key and try again.'
        };
      }
    }, `validateKey_${provider}_${key.substring(0, 8)}`);

    return debouncedValidate(provider, key);
  }

  /**
   * 测试API密钥连通性（带防抖和速率限制）
   */
  async testKeyConnection(provider: string, key: string, baseUrl: string): Promise<boolean> {
    if (!this.checkRateLimit('testConnection')) {
      throw new Error('Rate limit exceeded. Please try again later.');
    }

    const debouncedTest = this.debounce(async (prov: string, k: string, url: string) => {
      try {
        const response = await fetch(`${API_BASE}/keys/test`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Authorization': `Bearer ${this.getToken()}`,
            'X-CSRF-Token': this.getCSRFToken()
          },
          body: JSON.stringify({
            provider: prov,
            key: await this.encryptKey(k),
            baseUrl: url
          })
        });

        if (!response.ok) {
          return false;
        }

        const result = await response.json();
        return result.success;
      } catch (error) {
        console.error('Connection test failed');
        return false;
      }
    }, `testConnection_${provider}_${baseUrl}`);

    return debouncedTest(provider, key, baseUrl);
  }

  /**
   * 获取API密钥使用统计
   */
  async getKeyUsageStats(keyId: string): Promise<ApiKeyUsageStats> {
    try {
      const response = await fetch(`${API_BASE}/keys/${keyId}/usage`, {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${this.getToken()}`
        }
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Failed to fetch usage stats:', error);
      // 返回mock统计数据
      return {
        totalUsage: Math.floor(Math.random() * 10000),
        dailyUsage: Math.floor(Math.random() * 100),
        monthlyUsage: Math.floor(Math.random() * 3000),
        remainingQuota: Math.floor(Math.random() * 50000),
        lastUsedAt: new Date()
      };
    }
  }

  /**
   * 轮换API密钥
   */
  async rotateKey(keyId: string, newKey: string): Promise<ApiKey> {
    try {
      const response = await fetch(`${API_BASE}/keys/${keyId}/rotate`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.getToken()}`
        },
        body: JSON.stringify({
          newKey: this.encryptKey(newKey)
        })
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Failed to rotate API key:', error);
      throw error;
    }
  }

  /**
   * 将模型配置与API密钥关联
   */
  async linkConfigToKey(configId: string, keyId: string): Promise<void> {
    try {
      const response = await fetch(`${API_BASE}/keys/${keyId}/link`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.getToken()}`
        },
        body: JSON.stringify({ configId })
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }
    } catch (error) {
      console.error('Failed to link config to key:', error);
      throw error;
    }
  }

  /**
   * 获取审计日志
   */
  async getAuditLogs(keyId?: string): Promise<any[]> {
    try {
      const url = keyId 
        ? `${API_BASE}/keys/${keyId}/audit`
        : `${API_BASE}/keys/audit`;
        
      const response = await fetch(url, {
        method: 'GET',
        headers: {
          'Authorization': `Bearer ${this.getToken()}`
        }
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      return await response.json();
    } catch (error) {
      console.error('Failed to fetch audit logs:', error);
      return [];
    }
  }

  /**
   * 同步密钥到模型配置
   */
  async syncKeysToConfigs(configs: ModelConfigInfo[]): Promise<ModelConfigInfo[]> {
    try {
      const keys = await this.getAllKeys();
      const keyMap = new Map(keys.map(k => [`${k.provider}-${k.name}`, k]));

      return configs.map(config => {
        const key = keyMap.get(`${config.providerId}-${config.modelName}`);
        if (key) {
          return {
            ...config,
            // 保持完整的API密钥用于API调用
            apiKey: key.key,
            // 添加掩码版本用于UI显示
            displayApiKey: this.maskApiKey(key.key),
            keyId: key.id,
            keyStatus: key.status,
            keyExpiresAt: key.expiresAt
          };
        }
        return config;
      });
    } catch (error) {
      console.error('Failed to sync keys to configs:', error);
      return configs;
    }
  }

  private getToken(): string {
    return localStorage.getItem('authToken') || '';
  }

  private getMockKeys(): ApiKey[] {
    return [
      {
        id: 'key-1',
        name: 'OpenAI Production',
        key: 'sk-***masked***',
        provider: 'openai',
        createdAt: new Date('2025-09-01'),
        status: 'active',
        usageCount: 1250,
        usageLimit: 10000
      },
      {
        id: 'key-2',
        name: 'Claude API',
        key: 'sk-ant-***masked***',
        provider: 'claude',
        createdAt: new Date('2025-09-10'),
        status: 'active',
        usageCount: 850,
        usageLimit: 5000
      },
      {
        id: 'key-3',
        name: 'DeepSeek Development',
        key: 'sk-proj-***masked***',
        provider: 'deepseek',
        createdAt: new Date('2025-09-15'),
        status: 'inactive',
        usageCount: 0,
        usageLimit: 1000
      }
    ];
  }
}

export default new ApiKeyService();